package com.tuliyou.service.impl;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tuliyou.common.constant.ResponseStatusCodeConstant;
import com.tuliyou.common.util.Result;
import com.tuliyou.common.util.JwtUtil;
import com.tuliyou.common.util.UserHolder;
import com.tuliyou.common.util.ValidationUtil;
import com.tuliyou.mapper.ScoreRankMapper;
import com.tuliyou.request.LoginRequest;
import com.tuliyou.request.RegisterRequest;
import com.tuliyou.request.UpdateCurrentRequest;
import com.tuliyou.dto.UserDTO;
import com.tuliyou.entity.User;
import com.tuliyou.mapper.UserMapper;
import com.tuliyou.service.UserService;
import com.tuliyou.vo.LoginVO;
import jakarta.annotation.Resource;
import jakarta.transaction.Transactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import java.time.LocalDateTime;
import java.util.List;

import static com.tuliyou.common.constant.ResponseStatusCodeConstant.USER_ALREADY_EXISTS;

// UserServiceImpl.java
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    @Resource
    private UserMapper userMapper;

    @Resource
    private ScoreRankMapper scoreRankMapper;

    @Override
    @Transactional
    public Result<UserDTO> register(RegisterRequest request) {
        try {
            // 1. 参数格式校验,用户名，密码，邮箱，手机
            // 1.1 获得用户名，密码，邮箱，手机
            String username = request.getUsername();
            String password = request.getPassword();
            String email = request.getEmail();
            String phone = request.getPhone();
            List<String> errors = ValidationUtil.validateRegister(username, password, email, phone);
            if (!errors.isEmpty()) {
                return Result.error(errors.toString());
            }

            // 2. 检查用户名是否已存在
            if (userMapper.countByUsername(username) > 0) {
                return Result.error(USER_ALREADY_EXISTS,"用户名已存在");
            }

            // 3. 检查邮箱是否已存在（如果提供了邮箱）
            if (StringUtils.isNotBlank(email) &&
                    userMapper.countByEmail(email) > 0) {
                return Result.error("邮箱已被注册");
            }

            // 4. 检查手机号是否已存在（如果提供了手机号）
            if (StringUtils.isNotBlank(phone) &&
                    userMapper.countByPhone(phone) > 0) {
                return Result.error("手机号已被注册");
            }

            // 5. 创建用户对象
            User user = new User();
            user.setUsername(username);
            user.setPassword(DigestUtils.md5DigestAsHex(password.getBytes())); // MD5加密密码
            user.setEmail(email);
            user.setPhone(phone);
            user.setUserType("STUDENT"); // 默认学生类型
            user.setProvince("河北"); // 固定省份
            user.setExamType("PHYSICS"); // 固定科目组合
            user.setExamScore(request.getExamScore());
            user.setProvinceRank(request.getProvinceRank());
            user.setIsDeleted(0); // 未删除
            user.setCreatedAt(LocalDateTime.now());
            user.setUpdatedAt(LocalDateTime.now());

            // 6. 保存用户
            boolean saveResult = this.save(user);
            if (!saveResult) {
                log.error("用户注册失败：数据库保存失败，用户名：{}", username);
                return Result.error("注册失败，请稍后重试");
            }

            // 7. 返回用户DTO（不包含密码）
            UserDTO userDTO = UserDTO.fromUser(user);
            log.info("用户注册成功：{}", request.getUsername());
            return Result.success("注册成功", userDTO);

        } catch (Exception e) {
            log.error("用户注册异常：", e);
            throw new RuntimeException("注册过程发生异常", e);
        }
    }

    @Override
    public Result<LoginVO> login(LoginRequest request) {
        try {
            // 1. 参数校验
            if (StringUtils.isEmpty(request.getUsername()) || StringUtils.isEmpty(request.getPassword())) {
                return Result.paramError("用户名和密码不能为空");
            }

            // 2. 查询用户
            // 2.1 获得登录请求信息
            String username = request.getUsername();
            String password = request.getPassword();
            User user = query().eq("username", username).eq("is_deleted", 0).one();

            if (user == null) {
                log.warn("登录失败：用户不存在 - {}", username);
                return Result.error(ResponseStatusCodeConstant.USER_NOT_EXIST, "用户不存在");
            }

            // 3. 验证密码（MD5加密后比较）
            String encryptedPassword = DigestUtils.md5DigestAsHex(password.getBytes());
            if (!encryptedPassword.equals(user.getPassword())) {
                log.warn("登录失败：密码错误 - {}", request.getUsername());
                return Result.error(ResponseStatusCodeConstant.PASSWORD_ERROR, "密码错误");
            }

            // 4. 生成JWT令牌
            String token = JwtUtil.createToken(user.getId(), user.getUsername(), user.getUserType());

            // 5. 构建返回数据
            LoginVO loginVO = new LoginVO();
            loginVO.setToken(token);

            LoginVO.UserInfo userInfo = new LoginVO.UserInfo();
            userInfo.setId(user.getId());
            userInfo.setUsername(user.getUsername());
            userInfo.setUserType(user.getUserType());
            userInfo.setProvinceRank(user.getProvinceRank());
            loginVO.setUser(userInfo);

            log.info("用户登录成功：{}", user.getUsername());
            return Result.success("登录成功", loginVO);

        } catch (Exception e) {
            log.error("用户登录异常：", e);
            return Result.error("登录失败，请稍后重试");
        }
    }

    @Override
    public Result<UserDTO> getCurrentUser() {
        try {
            Long userId = UserHolder.getUser().getId();
            User user = query().eq("id", userId).eq("is_deleted", 0).one();
            UserDTO userDTO = UserDTO.fromUser(user);
            log.info("获取用户信息成功：{}", user.getUsername());
            return Result.success(userDTO);
        } catch (Exception e) {
            log.error("用户信息获取异常：",e);
            return Result.error("用户信息获取失败，请稍后重试");
        }
    }

    @Override
    public Result<UserDTO> updateCurrentUser(UpdateCurrentRequest request) {
        String email = request.getEmail();
        String phone = request.getPhone();
        Integer examScore = request.getExamScore();
        Integer provinceRank = request.getProvinceRank();
        /*// 1. 检查邮箱是否已存在（如果提供了邮箱）
        if (StringUtils.isNotBlank(email) &&
                userMapper.countByEmail(email) > 0) {
            return Result.error("邮箱已被注册");
        }*/

        /*// 2. 检查手机号是否已存在（如果提供了手机号）
        if (StringUtils.isNotBlank(phone) &&
                userMapper.countByPhone(phone) > 0) {
            return Result.error("手机号已被注册");
        }*/
        // 3. 如果存在考试分但不存在省排名，则自动查询对应的省排名并设置省排名到request里
        if (examScore != null && provinceRank == null) {
            provinceRank = scoreRankMapper.getRankByScore(examScore);
        }
        request.setProvinceRank(provinceRank);
        // 4. 用户信息修改
        try {
            Long userId = UserHolder.getUser().getId();
            int flag = userMapper.updateCurrentUser(request,userId);
            if (flag > 0) {
                User user = query().eq("id", userId).eq("is_deleted", 0).one();
                UserDTO userDTO = UserDTO.fromUser(user);
                log.info("用户信息修改成功：{}", user.getUsername());
                return Result.success(userDTO);
            }
            return Result.error("用户信息修改失败");
        } catch (Exception e) {
            log.info("用户信息修改异常：",e);
            return Result.error("用户信息修改异常，请稍后重试");
        }
    }

    @Override
    public Result logoff() {
        User user = UserHolder.getUser();
        try {
            Long userId = user.getId();
            int flag = userMapper.logoff(userId);
            if (flag > 0) {
                log.info("用户注销成功：{}", user.getUsername());
                return Result.success("用户注销成功");
            }
            return Result.error("用户注销失败");
        } catch (Exception e) {
            log.info("用户注销异常：",e);
            return Result.error("用户注销异常，请稍后重试");
        }
    }
}